#!/usr/bin/env python
"""
###############################################################################
# 用法：./visitor_sloc.py rootDir                                             #
# 把FileVisitor拓展成目录树里的各种类型的程序源代码文件的行数计数器，而且分类 #
# 显示不同类型                                                                #
# 程序的总数。                                                                #
# SLOC：source lines of code                                                  #
###############################################################################
"""

import os
import sys
import pprint
from visitor import FileVisitor


class LinesByType(FileVisitor):
    srcExts = []  # 在子类中定义

    def __init__(self, trace=1):
        FileVisitor.__init__(self, trace=trace)
        self.srcFCount = self.srcLCount = 0
        self.extSums = {ext: dict(files=0, lines=0) for ext in self.srcExts}

    def visitSrc(self, filePath, ext):
        if self.trace > 0:
            print(os.path.basename(filePath))

        try:
            lines = len(open(filePath).readlines())
        except Exception:
            print('错误： {} {} {}'.format(filePath, *sys.exc_info()[:2]))
        else:
            self.srcLCount += lines
            self.extSums[ext]['lines'] += lines

        self.srcFCount += 1
        self.extSums[ext]['files'] += 1

    def visitFile(self, filePath):
        FileVisitor.visitFile(self, filePath)
        for ext in self.srcExts:
            if filePath.endswith(ext):
                self.visitSrc(filePath, ext)
                break


class PyLines(LinesByType):
    srcExts = ['.py', '.pyw']  # 只有Python文件


class SourceLines(LinesByType):
    srcExts = ['.py', '.pyw', '.c', '.cxx', '.cgi', '.html', '.h', '.i']


def main():
    walker = SourceLines()
    walker.run(sys.argv[1])
    print('访问了 {} 个目录， {} 个文件'.format(walker.dirCount, walker.fileCount))
    print('-' * 79)
    print('共有 {} 个程序源代码文件，总共 {} 行'.format(walker.srcFCount, walker.srcLCount))
    print('按类型分：')
    pprint.pprint(walker.extSums)

    print('\n检查总数：')
    print('程序源代码文件 ->', sum(ext['files'] for ext in walker.extSums.values()))
    print('行数 ->', sum(ext['lines'] for ext in walker.extSums.values()))

    print('Python程序：')
    walker = PyLines(trace=0)
    walker.run(sys.argv[1])
    pprint.pprint(walker.extSums)


if __name__ == '__main__':
    main()
